package cn.com.mdx.sort.practice.collinearpoints;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p> 暴力破解方式
 *
 * @author ：huangy
 * @date ：Created in 2020/9/16 5:10 下午
 */
public class BruteCollinearPoints {

    /**
     * 点集合
     */
    private final Point[] points;

    public BruteCollinearPoints(Point[] points) {
        if (!checkPoints(points)) throw new IllegalArgumentException("点集不符合要求");
        this.points = points;
    }

    /**
     * @return int
     * @Author huangy
     * @description //TODO 共线线段条数
     * @date 3:52 下午 2020/9/17
     **/
    public int numberOfSegments() {
        return segments().length;
    }

    /**
     * @return cn.com.mdx.sort.practice.collinearpoints.LineSegment[] 线段集合
     * @Author huangy
     * @description //TODO 线段集合
     * @date 3:53 下午 2020/9/17
     **/
    public LineSegment[] segments() {
        //给点集排序
        Arrays.sort(points);
        List<LineSegment> lineSegmentList = new ArrayList<>();
        for (int i = 0; i < points.length; i++) {
            for (int j = i + 1; j < points.length; j++) {
                for (int k = j + 1; k < points.length; k++) {
                    for (int l = k + 1; l < points.length; l++) {
                        //计算i,j之间的斜率
                        double slopeIToJ = points[i].slopeTo(points[j]);
                        //计算i,k之间的斜率
                        double slopeIToK = points[i].slopeTo(points[k]);
                        //计算i,l之间的斜率
                        double slopeIToL = points[i].slopeTo(points[l]);
                        //如果斜率相同则表示线段共线
                        if (slopeIToJ == slopeIToK && slopeIToJ == slopeIToL)
                            lineSegmentList.add(new LineSegment(points[i], points[k]));
                    }
                }
            }
        }
        return lineSegmentList.toArray(new LineSegment[]{});
    }

    /**
     * @param points 被检测的点集
     * @return boolean false 不合法 true 合法
     * @Author huangy
     * @description //TODO 检测点集是否合法
     * @date 5:43 下午 2020/9/17
     **/
    private boolean checkPoints(Point[] points) {
        //点集数量大于4的情况不处理
        if (points == null || points.length < 4) return false;
        for (Point point : points)
            if (point == null) return false;
        return true;
    }

}
